package com.minit.connector.http;

import com.minit.connector.HttpRequestFacade;
import com.minit.connector.HttpResponseFacade;
import com.minit.startup.Bootstrap;
import org.apache.commons.lang3.text.StrSubstitutor;

import javax.servlet.ServletException;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.URL;
import java.net.URLClassLoader;
import java.net.URLStreamHandler;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;

public class ServletProcessor {

    private static String OKMessage = "HTTP/1.1 ${StatusCode} ${StatusName}\r\n" +
            "Content-Type: ${ContentType}\r\n" +
            "Server: minit\r\n" +
            "Date: ${ZonedDateTime}\r\n" +
            "\r\n";

    private HttpConnector connector;

    public ServletProcessor(HttpConnector connector) {
        this.connector = connector;
    }

    public void process(HttpRequestImpl request, HttpResponseImpl response) throws ServletException, IOException {
        this.connector.getContainer().invoke(request, response);
//        String uri = request.getUri();
//        String servletName = uri.substring(uri.indexOf("/") + 1);
//
//        response.setCharacterEncoding("UTF-8");
//
//        Class<?> servletClass = null;
//
//        try {
//            servletClass = HttpConnector.loader.loadClass(servletName);
//        } catch (ClassNotFoundException e) {
//            e.printStackTrace();
//        }
//
//        javax.servlet.Servlet servlet = null;
//
//        try {
//            servlet = ((javax.servlet.Servlet) servletClass.newInstance());
//            HttpRequestFacade requestFacade = new HttpRequestFacade(request);
//            HttpResponseFacade responseFacade = new HttpResponseFacade(response);
//            System.out.println("Call Service()");
//            servlet.service(requestFacade, responseFacade);
//        } catch (Exception e) {
//            e.printStackTrace();
//        }

    }

    public void oldProcess(HttpRequestImpl request, HttpResponseImpl response) {
        String uri = request.getUri();
        String servletName = uri.substring(uri.lastIndexOf("/") + 1);
        URLClassLoader loader = null;
        PrintWriter writer = null;
//        OutputStream output = null;

        try {
            URL[] urls = new URL[1];
            URLStreamHandler streamHandler = null;
            File classpath = new File(Bootstrap.WEB_ROOT);
            String repository = (new URL("file", null, classpath.getCanonicalPath() + File.separator)).toString();
            urls[0] = new URL(null, repository, streamHandler);
            loader = new URLClassLoader(urls);
        } catch (IOException io) {
            System.out.println(io);
        }

        try {
            response.setCharacterEncoding("UTF-8");
            writer = response.getWriter();
        } catch (IOException e) {
            e.printStackTrace();
        }

        // load class
        Class<?> servletClass = null;
        try {
            servletClass = loader.loadClass(servletName);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

//        String head = composeResponseHead();
//        writer.println(head);
        try {
            response.sendHeaders();
        } catch (IOException e) {
            e.printStackTrace();
        }

        javax.servlet.Servlet servlet = null;
        try {
            servlet = ((javax.servlet.Servlet) servletClass.newInstance());
            HttpRequestFacade requestFacade = new HttpRequestFacade(request);
            HttpResponseFacade responseFacade = new HttpResponseFacade(response);
            servlet.service(requestFacade, responseFacade);
        } catch (InstantiationException | IllegalAccessException | IOException | ServletException e) {
            e.printStackTrace();
        }
//        try {
//            output.flush();
//        } catch (IOException io) {
//            io.printStackTrace();
//        }
    }

    private String composeResponseHead() {
        Map<String, Object> valuesMap = new HashMap<>();
        valuesMap.put("StatusCode", "200");
        valuesMap.put("StatusName", "OK");
        valuesMap.put("ContentType", "text/html;charset=uft-8");
        valuesMap.put("ZonedDateTime", DateTimeFormatter.ISO_ZONED_DATE_TIME.format(ZonedDateTime.now()));
        StrSubstitutor sub = new StrSubstitutor(valuesMap);
        String responseHead = sub.replace(OKMessage);
        return responseHead;
    }
}
